package com.raft.core.log.sequence;

import java.util.List;

import com.raft.core.log.entry.Entry;
import com.raft.core.log.entry.EntryMeta;

/**日志条目序列
 * @author zhangsulei
 *
 */
public interface EntrySequence {

    /**判断是否为空
     * @return
     */
    boolean isEmpty();

    /**获取第一条日志的索引
     * @return
     */
    int getFirstLogIndex();

    /**获取最后一条日志的索引
     * @return
     */
    int getLastLogIndex();

    /**获取下一条日志的索引
     * @return
     */
    int getNextLogIndex();

    /**获取子视图，到最后一条日志
     * @param fromIndex
     * @return
     */
    List<Entry> subView(int fromIndex);

    /**获取序列的子视图，指定范围，不包括toIndex所指向的日志，用于构造AppendEntries消息时获取指定区间的日志条目
     * @param fromIndex
     * @param toIndex
     * @return
     */
    List<Entry> subList(int fromIndex, int toIndex);

    GroupConfigEntryList buildGroupConfigEntryList();

    /**检查某条日志是否存在
     * @param index
     * @return
     */
    boolean isEntryPresent(int index);

    /**获取指定索引的日志条目元信息
     * @param index
     * @return
     */
    EntryMeta getEntryMeta(int index);

    /**获取指定索引的日志条目
     * @param index
     * @return
     */
    Entry getEntry(int index);

    /**获取最后一个日志条目
     * @return
     */
    Entry getLastEntry();

    /**追加日志条目
     * @param entry
     */
    void append(Entry entry);

    /**追加多条日志
     * @param entries
     */
    void append(List<Entry> entries);

    /**推进commitIndex
     * @param index
     */
    void commit(int index);

    /**获取当前的commitIndex
     * @return
     */
    int getCommitIndex();

    /**移除某个索引之后的日志条目，用于追加来自Leader节点的日志时，出现日志冲突的情况下，移除现有日志
     * @param index
     */
    void removeAfter(int index);

    /**
     * 关闭日志序列
     */
    void close();

}
